package com.my.juc.sync;

/**
 * @author zhupanlin
 * @version 1.0
 * @description: TODO
 * @date 2024/3/5 15:03
 */

// 创建资源类，定义属性和操作方法
class Share{
    // 初始值
    private int number = 0;
    // 操作方法
    // 生产
    public synchronized void incr() throws InterruptedException {
        // 判断 干活 通知 睡眠
        while (number != 0){
            // 在哪里睡，就在哪里醒
            this.wait();
        }
        
        number++;
        System.out.println(Thread.currentThread().getName() + " :: " + number);
        // 通知其它线程
        this.notifyAll();
    }
    
    // 消费
    public synchronized void decr() throws InterruptedException {
        // 判断
        while (number == 0){
            this.wait();
        }
        
        // 干活
        number--;
        System.out.println(Thread.currentThread().getName() + " :: " + number);
        // 通知
        this.notifyAll();
    } 
}

public class ThreadDemo1 {

    public static void main(String[] args) {
        Share share = new Share();
        // 生产者
        new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    share.incr();
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }, "AA").start();
        
        // 消费者
        new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    share.decr();
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }, "BB").start();

        // 生产者
        new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    share.incr();
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }, "CC").start();

        // 消费者
        new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    share.decr();
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }, "DD").start();
        
    }
    
    
}
